#include "fileaccesser.h"

FileAccesser::FileAccesser(){}

int FileAccesser::openBinvoxFile(string filename, modelVolume* volume) {
    int version;
    int depth, height, width;
    int size;
    float tx, ty, tz;
    float scale;


    ifstream *input = new ifstream(filename.c_str(), ios::in | ios::binary);

    //
    // read header
    //
    string line;
    *input >> line;  // #binvox

    if (line.compare("#binvox") != 0) {
        cout << "Error: first line reads [" << line << "] instead of [#binvox]" << endl;
        delete input;
        return 0;
    }

    *input >> version;
    //cout << "reading binvox version " << version << endl;

    depth = -1;
    int done = 0;

    while(input->good() && !done) {
        *input >> line;
        if (line.compare("data") == 0) {
            done = 1;
        } else if (line.compare("dim") == 0) {
            *input >> depth >> height >> width;
        } else if (line.compare("translate") == 0) {
            *input >> tx >> ty >> tz;
        } else if (line.compare("scale") == 0) {
            *input >> scale;
        } else {
            cout << "  unrecognized keyword [" << line << "], skipping" << endl;
            char c;
            do {  // skip until end of line
                c = input->get();
            } while(input->good() && (c != '\n'));

        }
    }


    if (!done) {
        cout << "  error reading header" << endl;
        return 0;
    }

    if (depth == -1) {
        cout << "  missing dimensions in header" << endl;
        return 0;
    }

    size = width * height * depth;
    unsigned char voxels[size];

    //
    // read voxel data
    //
    unsigned char value;
    unsigned char count;
    int index = 0;
    int end_index = 0;
    int nr_voxels = 0;

    input->unsetf(ios::skipws);  // need to read every byte now (!)
    *input >> value;  // read the linefeed char

    while((end_index < size) && input->good()) {
        *input >> value >> count;

        if (input->good()) {
            end_index = index + count;
            if (end_index > size) {
                return 0;
            }

            for(int i=index; i < end_index; i++) {
                voxels[i] = value;
            }

            if (value) {
                nr_voxels += count;
            }

            index = end_index;
        }

    }

    input->close();
    cout << "  read " << nr_voxels << " voxels" << endl;

    int i = 0;

    for(int x = 0; x < depth; x++) {
        for(int z = 0; z < height; z++) {
            for(int y = 0; y < width; y++) {
                volume->getBlock(x,y,z)->type = voxels[i] == 1 ? Block_Dirt : Block_Air;
                i++;
            }
        }
    }



    return 1;
}
